LLM 究竟如何工作?#
在使用 Claude Code 的过程中,我一直有个疑惑:AI 是如何"理解"代码的?
表面上看,它能读懂代码逻辑、发现 bug、提出重构建议,这些都像是真正的"理解"。但仔细想想,LLM 的本质不就是"预测下一个词"吗?如果只是统计概率,为什么能解决复杂的编程问题?
这个问题一直困扰着我,直到我开始深入学习 LLM 的工作原理。我发现,理解 LLM 的能力边界,对于用好 Claude Code 至关重要。因为只有知道它"能做什么、不能做什么、为什么能做",才能合理地使用工具,避免不切实际的期待。
这篇文章,我会从 LLM 的本质讲起,解答以下问题:
- LLM 究竟是什么?和其他大模型有什么区别?
- 如果 LLM 只是"预测下一个词",它怎么能解决复杂问题?
- 为什么代码任务特别适合 LLM?
- Transformer 的注意力机制到底是什么?
- 为什么需要 Claude Code 这样的工具,而不只是 ChatGPT?
LLM 是什么#
本质定义#
LLM = Large Language Model(大语言模型)
它的本质是:基于大量文本数据训练的神经网络模型,专注于理解和生成自然语言。
更通俗的理解:
- 你给它一段文字(输入)
- 它预测接下来最可能出现的文字(输出)
- 通过这种方式完成对话、写作、翻译、代码生成等任务
与其他大模型的区别#
在研究 LLM 的过程中,我发现大模型其实有很多种类,按处理的数据类型可以分为:
| 类型 | 处理对象 | 典型代表 | 核心能力 |
|---|---|---|---|
| LLM | 文本 | GPT-4、Claude、Gemini | 逻辑推理、文字生成、代码理解 |
| VLM | 图像+文本 | GPT-4V、Claude 3.5 | 图片理解、图文对话 |
| Diffusion Model | 图像生成 | Stable Diffusion、Midjourney | 文生图、图像编辑 |
| Multimodal Model | 多种类型 | GPT-4o、Gemini Ultra | 跨模态理解与生成 |
核心差异:
- 训练数据不同:LLM 主要使用文本(网页、书籍、代码),图像模型使用图像+描述
- 应用场景不同:LLM 强在逻辑推理和文字生成,图像模型强在视觉创作
Claude Code 是 LLM 吗?#
这是一个容易混淆的概念。准确答案:Claude Code 不是 LLM,而是基于 LLM 构建的应用工具。
理解这个层次关系很重要:
Claude 3.5 Sonnet(LLM 模型)
↓ 理解和生成文本
Claude API(API 服务)
↓ 提供模型调用接口
Claude Code(应用工具)
↓ LLM + 工具系统(文件操作、代码执行、网络访问等)为什么这个区别重要?
因为它解释了:
- 为什么 Claude Code 能操作文件:LLM 本身不能,但工具系统可以
- 为什么 Claude Code 能执行代码:LLM 本身不能,但沙箱环境可以
- 为什么 Claude Code 有 Plan Mode:这是应用层的设计,不是模型能力
LLM 如何"理解":模式匹配 vs 真正理解#
一开始的困惑#
如果 LLM 只是"预测下一个词",为什么看起来像"理解"了?
这是我最困惑的点。比如:
- 问它"这段代码有什么问题",它能准确指出 bug
- 问它"如何重构这个函数",它能给出合理的建议
- 问它"解释这个算法的原理",它能讲得很清楚
这些都像是"理解",但如果只是统计模型,为什么能做到?
关键洞察:模式识别 ≠ 真正理解#
答案是:LLM 并不真正"理解",它是在做极其复杂的模式匹配。
用一个对比来说明:
人类理解 = 概念 + 因果关系 + 抽象推理
LLM "理解" = 海量模式 + 统计关联 + 上下文推理具体过程:
训练阶段:见过海量的"问题→答案"模式
见过 10000+ 次:"天气怎么样" → "今天是晴天/雨天/..."
见过 50000+ 次:"这段代码有 bug" → 分析 + 解决方案
见过 100000+ 次:代码上下文 → 合理的代码补全推理阶段:通过注意力机制组合模式
你的输入:"我在杭州,明天天气怎么样"
LLM 内部处理:
- "我在杭州" → 地点信息(高关注度)
- "明天" → 时间信息(高关注度)
- "天气" → 查询类型(高关注度)
- 组合这些模式 → 生成符合模式的输出但这不是真正的理解#
举个例子就能看出差异:
问:如果一个人从高楼跳下,会发生什么?
LLM:会受重力影响下落,可能受伤或死亡
问:如果一个人从高楼"往上"跳,会发生什么?
LLM:仍然会受重力影响下落(匹配到"从高楼跳"的模式)LLM 不理解:
- "往上跳"的物理含义(人无法违反重力)
- 这是一个不合理的问题
它只是匹配:
- "高楼 + 跳" → 坠落场景
关于训练数据的局限#
这也解释了为什么 LLM 对训练数据之后的内容"不知道":
如果你问:"2024 年最新的网络梗是什么?"
LLM 可能:
- 诚实回答"我不知道"(训练数据截止于 2024 年 1 月)
- 编造答案(幻觉)
但如果你提供上下文:
"最近流行一个梗'xx',意思是..."
LLM:能理解!因为有上下文本质:LLM 的"理解"依赖于:
- 训练数据中的模式
- 当前对话的上下文
- 两者的组合
为什么"预测下一个词"能解决复杂问题#
关键机制:思维链(Chain-of-Thought)#
虽然 LLM 不"理解",但它能"模仿推理":
简单任务:直接预测
你:"1+1=?"
LLM:"2"
复杂任务:分步推理
你:"一个项目有 10 个文件,每个文件平均 100 行,重构需要多久?"
LLM 内部推理链:
"这需要分步思考" →
"第一步:总代码量 = 10 * 100 = 1000 行" →
"第二步:重构速度取决于复杂度..." →
"第三步:综合考虑..." →
最终答案为什么有效?
因为训练数据中包含大量"推理过程":
- 教科书的分步解题
- 代码注释的逻辑说明
- 博客文章的思路展开
**LLM 学会了"模仿推理"**:
- 不是真正的逻辑推理
- 而是学习到了"什么样的推理过程是合理的"模式
代码生成的例子#
代码上下文:
def calculate_total(items):
# 计算所有商品的总价
total = 0
for item in items:
total += ___
问题:下划线处应该填什么?LLM 的处理过程:
- 识别模式:"total +=" → 累加操作
- 分析上下文:"items" → 商品列表,"item" → 当前商品
- 提取关键信息:"总价" + "商品" → 需要价格属性
- 组合模式:
item.price
为什么代码任务特别适合 LLM#
在学习过程中,我发现了一个有趣的现象:LLM 在代码任务上的表现,往往比自然语言任务更稳定。这是为什么?
1. 代码的规范性强#
自然语言:"今天天气真好"
可能的延续:
- "我们去郊游吧"(建议)
- "是啊,很适合运动"(认同)
- "但我心情不好"(转折)
- ... 无限可能
代码:"function add(a, b) {"
可能的延续:
- "return a + b;" (高概率,符合函数名)
- "return a - b;" (低概率,不符合函数名)
- "console.log('hello');" (极低概率,不符合逻辑)关键差异:
| 维度 | 自然语言 | 代码 |
|---|---|---|
| 语法规则 | 灵活、模糊 | 严格、确定 |
| 验证方式 | 主观理解 | 可执行、可测试 |
| 正确性 | "合理即可" | "正确或错误" |
2. "合理" vs "正确"#
自然语言任务:
问:"今天心情不好,怎么办?"
回答 A:"去运动一下"
回答 B:"找朋友聊聊"
回答 C:"听音乐放松"
→ 都合理,没有绝对的"对错"
编程任务:
问:"写一个排序函数"
回答 A:正确的快速排序
回答 B:有 bug 的快速排序
回答 C:正确的冒泡排序
→ 有明确的"对错"3. 代码的可组合性#
代码比自然语言更容易组合和复用:
自然语言:
句子 A:"我喜欢吃苹果"
句子 B:"苹果很健康"
组合:"我喜欢吃苹果,苹果很健康"
→ 需要调整语序、添加连接词
代码:
函数 A:function readFile(path) { ... }
函数 B:function parseJSON(text) { ... }
组合:const data = parseJSON(readFile(path))
→ 直接组合,无需修改对 LLM 的意义:
模式复用更容易:
见过:读取文件 → 解析 JSON 见过:读取文件 → 解析 CSV 推理:读取文件 → 解析 YAML(新组合)上下文依赖更清晰:
// 函数签名明确输入输出 function add(a: number, b: number): number // LLM 知道:输入类型、输出类型、行为预期错误反馈更精确:
自然语言:"这句话不太对"(模糊) 代码:"TypeError: expected string, got number"(精确)
Transformer:LLM 的"超能力"来源#
用类比理解:阅读理解考试#
想象你在做一道阅读理解题:
传统方式(RNN/LSTM):
文章:"小明早上起床,刷牙洗脸,然后去学校上课。"
问题:"小明去哪里了?"
传统模型(从左到右逐字处理):
"小明" → 记住
"早上" → 更新记忆
"起床" → 更新记忆
...
"学校" → 更新记忆(前面的信息已经模糊了)
问题:像流水账,前面的容易忘Transformer 方式(注意力机制):
文章:"小明早上起床,刷牙洗脸,然后去学校上课。"
问题:"小明去哪里了?"
Transformer(全局注意力):
看到"去"这个词时,同时看整个句子,判断相关性:
- "小明" → 关联度:90%(主语,重要!)
- "早上" → 关联度:10%(时间,不重要)
- "起床" → 关联度:10%(动作,不重要)
- "学校" → 关联度:95%(地点,核心答案!)
综合分析:
"去" + "学校" 关联强 → 地点是学校
"小明" + "去" 关联强 → 主语是小明注意力机制的本质#
注意力的本质:为每个词计算它与其他所有词的"相关性"
句子:"The cat sat on the mat."
当处理 "sat" 这个词时:
传统模型:
The → cat → sat
→ 只记得前面的 "The cat"
Transformer:
sat 与所有词的注意力分数:
- The: 0.1(冠词,不重要)
- cat: 0.9(主语,重要!)
- sat: 1.0(当前词)
- on: 0.3(介词,有点重要)
- the: 0.1(冠词,不重要)
- mat: 0.6(地点,重要)
综合理解:
"cat" 执行了 "sat" 的动作
动作发生在 "mat" 上注意力权重的可视化#
句子:"我喜欢吃北京烤鸭"
处理"烤鸭"时的注意力权重:
我 10% (主语,略相关)
喜欢 30% (动词,比较相关)
吃 80% (动作,很相关!)
北京 95% (修饰词,极相关!)
烤鸭 100% (当前词)
结论:
- "烤鸭"主要关注"北京"(地名修饰)
- "烤鸭"关注"吃"(动作对象)
- 理解为:"吃 + 北京的 + 烤鸭"为什么这个机制如此强大#
1. 并行处理
传统 RNN:
word1 → word2 → word3 → word4
→ 必须顺序处理,慢
Transformer:
word1 ────┐
word2 ────┤→ 同时计算所有注意力 → 并行处理
word3 ────┤
word4 ────┘
→ 所有词同时处理,快!2. 长距离依赖
句子:"我昨天在北京吃了一顿很美味的烤鸭。"
问题:"在哪里吃的?"
传统模型:
从"我"到"烤鸭"要处理 10+ 个词
中间信息容易丢失
Transformer:
"吃" 可以直接"注意"到"北京"
不管距离多远,注意力权重直接计算3. 多头注意力(Multi-Head Attention)
类比:用不同的视角同时看文章
文章:"小明在学校学习编程。"
Head 1(关注"谁"):
小明 主语
学校 地点(略相关)
Head 2(关注"在哪"):
学校 地点
学习 动作(略相关)
Head 3(关注"做什么"):
学习 动作
编程 对象
综合三个视角 → 完整理解:
"小明(谁)在学校(哪)学习编程(做什么)"代码理解的例子#
代码:
const user = await fetchUser(userId);
const orders = await fetchOrders(user.id);
const total = calculateTotal(orders);
return { user, orders, total };
Transformer 的优势:
1. 同时"看到"所有行
2. 理解 userId → user.id → orders 的数据流
3. 理解 orders → calculateTotal → total 的转换
4. 理解最终返回的结构
这就是为什么 LLM 能:
- 理解代码逻辑
- 发现潜在 bug
- 建议重构方案LLM 的能力边界#
理解了 LLM 的工作原理后,我们也能更清楚地认识它的局限:
| 维度 | LLM 能做到 | LLM 做不到 |
|---|---|---|
| 理解 | 模式匹配、上下文推理 | 真正的语义理解、因果推理 |
| 记忆 | 基于上下文"记住" | 长期记忆、跨会话记忆 |
| 推理 | 模仿推理过程 | 严格的逻辑证明 |
| 创造 | 组合已知模式 | 真正的创新 |
| 验证 | 生成看似合理的内容 | 保证事实正确 |
典型的能力边界#
能做好的:
- 样板代码生成
- API 使用示例
- 代码解释与重构
- 简单 Bug 修复
做不好的:
- 复杂系统架构设计
- 性能优化(需要数据驱动)
- 安全审计(需要严格验证)
- 超长代码库的全局理解
为什么需要工具增强#
基于上面的分析,我们能清楚地看到:LLM 单独使用有很大局限。
LLM 的三大局限#
- 上下文窗口有限:无法加载整个项目
- 无法执行代码:无法验证生成的代码是否正确
- 无法访问外部资源:无法读取文件、调用 API
工具系统的三个核心价值#
价值 1:自动化上下文获取
没有工具:
用户:"帮我修复这个 bug"
LLM:"请提供代码"
用户:复制粘贴代码
LLM:"请提供错误信息"
用户:复制粘贴错误
→ 效率低、容易遗漏
有工具(Claude Code):
用户:"帮我修复这个 bug"
Claude Code:
1. Read(错误文件) → 自动获取代码
2. Bash(npm test) → 自动获取错误信息
3. Grep(相关函数) → 自动获取依赖关系
4. 分析 → 修复 → 验证
→ 效率高、上下文完整价值 2:执行验证与迭代
传统方式(ChatGPT):
AI 生成代码 → 用户复制 → 用户粘贴 → 用户运行 → 有错误 → 用户再问 AI
→ 每一步都可能出错
Claude Code:
AI 生成代码 → 自动写入文件 → 自动运行测试 → 有错误 → 自动读取错误 → AI 自动修正
→ 减少人工环节,提高稳定性这就是"执行-验证-调整"循环:
计划实施 → 执行代码 → 检查结果 → 发现问题 → 调整方案 → 再次执行
↑ ↓
└──────────────────────────────────────────────┘价值 3:扩展能力边界
LLM 本身不能做的事,工具可以做:
| 任务 | LLM 能力 | 工具能力 | 组合效果 |
|---|---|---|---|
| 读取文件 | ❌ | ✅ Read | LLM 分析 + 工具读取 |
| 执行代码 | ❌ | ✅ Bash | LLM 生成 + 工具执行 |
| 搜索代码库 | ❌ | ✅ Grep | LLM 理解 + 工具搜索 |
| 访问网络 | ❌ | ✅ WebFetch | LLM 提取 + 工具获取 |
| 调用 API | ❌ | ✅ MCP | LLM 规划 + 工具调用 |
Claude Code 的本质#
Claude Code = LLM(大脑)+ 工具系统(手脚)
大脑:理解需求、制定计划、分析问题
手脚:执行操作、获取信息、验证结果为什么理解 LLM 很重要#
通过这篇文章的学习,我对 LLM 有了更清晰的认知:
LLM 的本质:
- 不是"真正理解",而是"复杂的模式匹配"
- 基于 Transformer 的注意力机制
- 能力来自于训练数据和上下文
为什么代码任务适合 LLM:
- 代码规范性强,适合模式匹配
- 可组合性好,容易复用
- 可验证性强,有明确的对错
为什么需要工具增强:
- LLM 有能力边界(无法执行、无法访问外部)
- 工具系统补足了 LLM 的短板
- 组合产生了 1+1>2 的效果
对使用 Claude Code 的启示:
- 提供充分上下文:LLM 的输出质量取决于输入
- 善用工具能力:让 Claude Code 自动获取信息、执行验证
- 理解能力边界:不要期待 LLM 做它做不到的事
- 建立迭代思维:执行-验证-调整,而不是一次性完成
下一篇文章,我会深入探讨 Prompt Engineering 的核心技巧,教你如何更有效地与 AI 对话。